using Microsoft.AspNetCore.Mvc;
using SG3L_RAG.Application.Interfaces;
using SG3L_RAG.Application.DTOs;

namespace SG3L_RAG.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class SearchController : ControllerBase
    {
        private readonly IVectorSearchService _vectorSearchService;
        private readonly IDocumentService _documentService;
        private readonly ILogger<SearchController> _logger;

        public SearchController(
            IVectorSearchService vectorSearchService,
            IDocumentService documentService,
            ILogger<SearchController> logger)
        {
            _vectorSearchService = vectorSearchService;
            _documentService = documentService;
            _logger = logger;
        }

        /// <summary>
        /// 向量搜索相似文档（推荐使用，支持强类型DTO）
        /// </summary>
        /// <param name="request">搜索请求</param>
        /// <returns>搜索结果</returns>
        [HttpPost("documents")]
        public async Task<ActionResult<List<DocumentSearchResultDto>>> SearchSimilarDocuments([FromBody] VectorSearchRequestDto request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Query))
                {
                    return BadRequest(new { error = "查询内容不能为空" });
                }

                _logger.LogInformation("向量搜索文档，查询: {Query}, TopK: {TopK}, 阈值: {Threshold}", 
                    request.Query, request.TopK, request.Threshold);

                var results = await _vectorSearchService.SearchSimilarDocumentsAsync(
                    request.Query,
                    request.TopK,
                    request.Threshold);

                return Ok(results);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "向量搜索文档时发生错误: {Query}", request.Query);
                return StatusCode(500, new { error = $"搜索失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 向量搜索相似文档分片（推荐使用，支持强类型DTO）
        /// </summary>
        /// <param name="request">搜索请求</param>
        /// <returns>搜索结果</returns>
        [HttpPost("chunks")]
        public async Task<ActionResult<List<DocumentChunkSearchResultDto>>> SearchSimilarChunks([FromBody] VectorSearchRequestDto request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Query))
                {
                    return BadRequest(new { error = "查询内容不能为空" });
                }

                _logger.LogInformation("向量搜索文档分片，查询: {Query}, TopK: {TopK}, 阈值: {Threshold}", 
                    request.Query, request.TopK, request.Threshold);

                var results = await _vectorSearchService.SearchSimilarChunksAsync(
                    request.Query,
                    request.TopK,
                    request.Threshold);

                return Ok(results);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "向量搜索文档分片时发生错误: {Query}", request.Query);
                return StatusCode(500, new { error = $"搜索失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 搜索相似文档（兼容性接口，支持GET查询参数）
        /// </summary>
        /// <param name="q">搜索查询</param>
        /// <param name="limit">返回结果数量限制</param>
        /// <param name="threshold">相似度阈值</param>
        /// <returns>搜索结果</returns>
        [HttpGet("documents")]
        public async Task<ActionResult<object>> SearchDocumentsLegacy(
            [FromQuery] string q,
            [FromQuery] int limit = 5,
            [FromQuery] float threshold = 0.7f)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(q))
                {
                    return BadRequest(new { error = "搜索查询不能为空" });
                }

                _logger.LogInformation("搜索文档（兼容性接口），查询: {Query}, 限制: {Limit}", q, limit);

                var searchResults = await _vectorSearchService.SearchSimilarDocumentsAsync(q, limit, threshold);

                var results = searchResults.Select(r => new
                {
                    documentId = r.DocumentId,
                    title = r.Title,
                    summary = r.Summary,
                    score = r.Score,
                    relevantChunks = r.RelevantChunks.Select(c => new
                    {
                        chunkId = c.ChunkId,
                        content = c.Content,
                        chunkIndex = c.ChunkIndex,
                        score = c.Score,
                        highlightedContent = c.HighlightedContent
                    }).ToList()
                }).ToList();

                return Ok(new
                {
                    query = q,
                    totalResults = results.Count,
                    results = results,
                    searchTime = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "搜索文档时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 搜索相似文档分片（兼容性接口，支持GET查询参数）
        /// </summary>
        /// <param name="q">搜索查询</param>
        /// <param name="limit">返回结果数量限制</param>
        /// <param name="threshold">相似度阈值</param>
        /// <returns>搜索结果</returns>
        [HttpGet("chunks")]
        public async Task<ActionResult<object>> SearchChunksLegacy(
            [FromQuery] string q,
            [FromQuery] int limit = 10,
            [FromQuery] float threshold = 0.7f)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(q))
                {
                    return BadRequest(new { error = "搜索查询不能为空" });
                }

                _logger.LogInformation("搜索文档分片（兼容性接口），查询: {Query}, 限制: {Limit}", q, limit);

                var searchResults = await _vectorSearchService.SearchSimilarChunksAsync(q, limit, threshold);

                // 获取相关文档信息
                var documentIds = searchResults.Select(r => r.DocumentId).Distinct().ToList();
                var allDocuments = await _documentService.GetAllAsync();
                var documentDict = allDocuments.Where(d => documentIds.Contains(d.Id))
                    .ToDictionary(d => d.Id);

                var results = searchResults.Select(r => new
                {
                    chunkId = r.ChunkId,
                    documentId = r.DocumentId,
                    documentTitle = documentDict.ContainsKey(r.DocumentId) ? documentDict[r.DocumentId].Name : "未知文档",
                    content = r.Content,
                    chunkIndex = r.ChunkIndex,
                    score = r.Score,
                    highlightedContent = r.HighlightedContent
                }).ToList();

                return Ok(new
                {
                    query = q,
                    totalResults = results.Count,
                    results = results,
                    searchTime = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "搜索文档分片时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 为指定文档建立索引
        /// </summary>
        /// <param name="documentId">文档ID</param>
        /// <returns>操作结果</returns>
        [HttpPost("index/{documentId:guid}")]
        public async Task<ActionResult> IndexDocument(Guid documentId)
        {
            try
            {
                _logger.LogInformation("为文档 {DocumentId} 建立索引", documentId);

                var success = await _vectorSearchService.IndexDocumentAsync(documentId);
                
                if (success)
                {
                    return Ok(new { success = true, message = "文档索引创建成功" });
                }
                else
                {
                    return NotFound(new { success = false, error = "文档不存在或索引创建失败" });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "为文档 {DocumentId} 建立索引时发生错误", documentId);
                return StatusCode(500, new { success = false, error = $"索引创建失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 从索引中移除指定文档
        /// </summary>
        /// <param name="documentId">文档ID</param>
        /// <returns>操作结果</returns>
        [HttpDelete("index/{documentId:guid}")]
        public async Task<ActionResult> RemoveDocumentFromIndex(Guid documentId)
        {
            try
            {
                _logger.LogInformation("从索引中移除文档 {DocumentId}", documentId);

                var success = await _vectorSearchService.RemoveDocumentFromIndexAsync(documentId);
                
                if (success)
                {
                    return Ok(new { success = true, message = "文档从索引中移除成功" });
                }
                else
                {
                    return BadRequest(new { success = false, error = "从索引中移除文档失败" });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "从索引中移除文档 {DocumentId} 时发生错误", documentId);
                return StatusCode(500, new { success = false, error = $"移除索引失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 文档关键词搜索（基于标题和内容的简单文本搜索）
        /// </summary>
        /// <param name="keyword">关键词</param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns>搜索结果</returns>
        [HttpGet("text")]
        public async Task<ActionResult<object>> TextSearch(
            [FromQuery] string keyword,
            [FromQuery] int page = 1,
            [FromQuery] int pageSize = 20)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(keyword))
                {
                    return BadRequest(new { error = "搜索关键词不能为空" });
                }

                _logger.LogInformation("文本搜索，关键词: {Keyword}", keyword);

                var allDocuments = await _documentService.GetAllAsync();
                
                // 简单的文本匹配搜索
                var matchedDocuments = allDocuments
                    .Where(d => d.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase))
                    .ToList();

                var totalCount = matchedDocuments.Count;
                var skip = (page - 1) * pageSize;
                var pagedResults = matchedDocuments.Skip(skip).Take(pageSize).ToList();

                var results = pagedResults.Select(d => new
                {
                    documentId = d.Id,
                    title = d.Name,
                    fileName = d.Name,
                    fileType = d.Type,
                    fileSize = 0, // Document实体中没有Size属性
                    status = d.Status,
                    uploaderId = d.UploaderId,
                    createdAt = d.CreatedAt,
                    updatedAt = d.UpdatedAt,
                    // 简单的高亮处理
                    highlightedTitle = HighlightKeyword(d.Name, keyword)
                }).ToList();

                return Ok(new
                {
                    keyword = keyword,
                    totalResults = totalCount,
                    page = page,
                    pageSize = pageSize,
                    totalPages = (int)Math.Ceiling((double)totalCount / pageSize),
                    hasNextPage = totalCount > skip + pageSize,
                    results = results,
                    searchTime = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "文本搜索时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 获取搜索建议
        /// </summary>
        /// <param name="q">查询前缀</param>
        /// <param name="limit">建议数量限制</param>
        /// <returns>搜索建议</returns>
        [HttpGet("suggestions")]
        public async Task<ActionResult<object>> GetSuggestions(
            [FromQuery] string q,
            [FromQuery] int limit = 10)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(q) || q.Length < 2)
                {
                    return Ok(new { suggestions = new string[0] });
                }

                var allDocuments = await _documentService.GetAllAsync();
                
                // 基于文档标题生成搜索建议
                var suggestions = allDocuments
                    .Where(d => d.Name.Contains(q, StringComparison.OrdinalIgnoreCase))
                    .Select(d => d.Name)
                    .Distinct()
                    .Take(limit)
                    .ToList();

                // 添加一些常见的搜索查询建议
                var commonQueries = new[]
                {
                    "如何使用", "什么是", "怎么做", "为什么", "如何配置", "如何安装",
                    "使用方法", "操作步骤", "注意事项", "常见问题"
                };

                var queryBasedSuggestions = commonQueries
                    .Where(cq => cq.Contains(q, StringComparison.OrdinalIgnoreCase))
                    .Take(Math.Max(0, limit - suggestions.Count))
                    .ToList();

                suggestions.AddRange(queryBasedSuggestions);

                return Ok(new
                {
                    query = q,
                    suggestions = suggestions.Take(limit).ToList()
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取搜索建议时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 重建搜索索引
        /// </summary>
        /// <returns>重建结果</returns>
        [HttpPost("index/rebuild")]
        public async Task<ActionResult<object>> RebuildIndex()
        {
            try
            {
                _logger.LogInformation("开始重建搜索索引");

                var success = await _vectorSearchService.RebuildIndexAsync();

                if (success)
                {
                    return Ok(new
                    {
                        success = true,
                        message = "搜索索引重建成功",
                        rebuiltAt = DateTime.UtcNow
                    });
                }
                else
                {
                    return BadRequest(new
                    {
                        success = false,
                        error = "搜索索引重建失败"
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重建搜索索引时发生错误");
                return StatusCode(500, new { success = false, error = $"重建索引失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 简单的关键词高亮处理
        /// </summary>
        /// <param name="text">文本</param>
        /// <param name="keyword">关键词</param>
        /// <returns>高亮后的文本</returns>
        private string HighlightKeyword(string text, string keyword)
        {
            if (string.IsNullOrWhiteSpace(text) || string.IsNullOrWhiteSpace(keyword))
                return text;

            return System.Text.RegularExpressions.Regex.Replace(
                text,
                System.Text.RegularExpressions.Regex.Escape(keyword),
                $"<mark>{keyword}</mark>",
                System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        }
    }
}
